﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Mindscape.LightSpeed;
using OrmSmackdown.LightSpeedORM.Mappings;

namespace OrmSmackdown.LightSpeedORM
{
    public class Aggregate : IAggregate
    {
        
        private LightSpeedContext<Mappings.OrmSmackdownUnitOfWork> ctx;
        private Mappings.OrmSmackdownUnitOfWork uow;

       
        public Aggregate()
        {
            ctx = new LightSpeedContext<OrmSmackdownUnitOfWork>();
            ctx.ConnectionString = LightSpeedContext.Default.ConnectionString;
            ctx.PluralizeTableNames = LightSpeedContext.Default.PluralizeTableNames;
            ctx.IdentityMethod = LightSpeedContext.Default.IdentityMethod;

            uow = ctx.CreateUnitOfWork();
            
        }

        public void InsertRecordsApproachOne(int recordsToInsert)
        {
            using (var uow = ctx.CreateUnitOfWork())
            {
                for(var idx = 0; idx < recordsToInsert; ++ idx)
                {
                    uow.Add(new Mappings.Performance() { MilliSeconds = idx, Action = Constants.STR_AggregateCount, OrmName = "LightSpeedORM" });
                }

                uow.SaveChanges();
            }
        }


        public void InsertRecordsApproachTwo(int recordsToInsert)
        {
            using (var uow = ctx.CreateUnitOfWork())
            {
                for (var idx = 0; idx < recordsToInsert; ++idx)
                {
                    uow.Add(new Mappings.Performance() { MilliSeconds = idx, Action = Constants.STR_AggregateCount, OrmName = "LightSpeedORM" });
                }

                uow.SaveChanges();
            }         
        }

        public int GetCountApproachOne()
        {
            return uow.Performance.Count(perf => perf.Action == Constants.STR_AggregateCount);
        }

        public int GetCountApproachTwo()
        {
            var query = from perf
                         in uow.Performance
                        where perf.Action == Constants.STR_AggregateCount
                        select perf.MilliSeconds;

            return query.ToList().Count();
        }

        public int GetAverageApproachOne()
        {
            return Convert.ToInt32(uow.Performance.Where(perf => perf.Action == Constants.STR_AggregateCount).Average(perf => perf.MilliSeconds));
        }

        public int GetAverageApproachTwo()
        {
            var query = from perf
                         in uow.Performance
                        where perf.Action == Constants.STR_AggregateCount
                        select perf.MilliSeconds;

            return Convert.ToInt32(query.Average());
        }

        public void DeleteRecordsApproachOne()
        {
            AdoNet.Aggregate.ClearAggregateCounts();
        }

        public void DeleteRecordsApproachTwo()
        {
            AdoNet.Aggregate.ClearAggregateCounts();
        }

        public void Dispose()
        {
            uow.Dispose();
        }
    }
}
